using System;
using System.ComponentModel;
using System.Globalization;
using System.Collections;
using System.Drawing.Design;

using SharpGL.SceneGraph.Assets;

namespace SharpGL.SceneGraph
{
    /// <summary>
    ///	This namespace contains classes for use with the .NET design surface,
	///	typeconverters, UI editors etc. Most clients can safely ingore this, 
	///	it's not important 3D code, it just makes editing it easier.
    ///	</summary>
	namespace NETDesignSurface
	{
        /// <summary>
        ///	Designers are used to aid design of controls, components etc.
        ///	</summary?
		namespace Designers
		{
			/// <summary>
			/// This aids the design of the OpenGLCtrl
			/// </summary>
			public class OpenGLCtrlDesigner : System.Windows.Forms.Design.ControlDesigner 
			{
                /// <summary>
                /// Initializes a new instance of the <see cref="OpenGLCtrlDesigner"/> class.
                /// </summary>
				public OpenGLCtrlDesigner()
                {
                }

				/// <summary>
				/// Remove Control properties that are not supported by the control.
				/// </summary>
				/// <param name="Properties"></param>
				protected override void PostFilterProperties(IDictionary Properties)
				{
					//	Appearance
					Properties.Remove("BackColor");
					Properties.Remove("BackgroundImage");
					Properties.Remove("Font");
					Properties.Remove("ForeColor");
					Properties.Remove("RightToLeft");

					//	Behaviour
					Properties.Remove("AllowDrop");
					Properties.Remove("ContextMenu");

					//	Layout
					Properties.Remove("AutoScroll");
					Properties.Remove("AutoScrollMargin");
					Properties.Remove("AutoScrollMinSize");
				}
			}
		}

        /// <summary>
        ///	Converters are used to change objects of one type into another, at design time
		///	and also programmatically.
        ///	</summary>
		namespace Converters
		{
			/// <summary>
			/// This converts the Material Collection into something more functional.
			/// </summary>
			internal class MaterialCollectionConverter : System.ComponentModel.CollectionConverter 
			{ 
				public override object ConvertTo(ITypeDescriptorContext context, 
					CultureInfo culture, object value, Type destinationType) 
				{ 
					if (destinationType == typeof(string)) 
					{ 
						if (value is System.Collections.ICollection) 
							return "Materials"; 
					} 
 
					return base.ConvertTo(context, culture, value, destinationType); 
				} 
			}
		}

        /// <summary>
        ///	Editors are classes that increase the functionality of the properties window
		///	in editing objects, e.g texture objects have a thumbnail.
        ///	</summary>
		namespace Editors
		{
			/// <summary>
			/// The texture editor makes Textures in the properties window much better,
			/// giving them a little thumbnail.
			/// </summary>
			internal class UITextureEditor : UITypeEditor
			{
				public override System.Boolean GetPaintValueSupported(System.ComponentModel.ITypeDescriptorContext context )
				{
					return true;
				}

				public override void PaintValue(System.Drawing.Design.PaintValueEventArgs e)
				{
					//	Make sure we are dealing with an actual texture.
					if(e.Value is Texture2D)
					{
						//	Get the texture.
						Texture2D tex = e.Value as Texture2D;

                        if (tex.TextureName != 0)
                        {
                            System.Drawing.Bitmap bitmap = tex.ToBitmap();
                            if (bitmap != null)
                                e.Graphics.DrawImage(tex.ToBitmap(), e.Bounds);
                        }
					}
				}
			}

			/// <summary>
			/// This converts the Quadric Collection into something more functional, and
			/// allows you to add many types of quadrics.
			/// </summary>
			internal class QuadricCollectionEditor : System.ComponentModel.Design.CollectionEditor
			{  
				public QuadricCollectionEditor(Type type)
                    : base(type)
                {
                }

                /// <summary>
                ///	Return the types that you want to allow the user to add into your collection. 
                ///	</summary>
				protected override Type[] CreateNewItemTypes() 
				{
					return new Type[] {typeof(Quadrics.Cylinder), typeof(Quadrics.Disk), typeof(Quadrics.Sphere)}; 
				}
			}

			/// <summary>
			/// This converts the Camera collection into something more usable (design time wise)
			/// by allowing all the types of camera to be added.
			/// </summary>
			internal class CameraCollectionEditor : System.ComponentModel.Design.CollectionEditor
			{  
				public CameraCollectionEditor(Type type)
                    : base(type)
                {
                }

                /// <summary>
                ///	Return the types that you want to allow the user to add into your collection. 
                ///	</summary>
				protected override Type[] CreateNewItemTypes() 
				{
					return new Type[] {typeof(Cameras.FrustumCamera), typeof(Cameras.OrthographicCamera), typeof(Cameras.PerspectiveCamera), typeof(Cameras.ArcBallCamera)}; 
				}
			}
            
            /// <summary>
            /// This converts the Effect collection into something more usable (design time wise)
            /// by allowing all the types of effect to be added.
            /// </summary>
            internal class EffectCollectionEditor : System.ComponentModel.Design.CollectionEditor
            {
                public EffectCollectionEditor(Type type)
                    : base(type)
                {
                }

                /// <summary>
                ///	Return the types that you want to allow the user to add into your collection. 
                ///	</summary>
                protected override Type[] CreateNewItemTypes()
                {
                    return new Type[] { /*typeof(Effects.ArcBallTransformationEffect), */typeof(Effects.LinearTransformationEffect), typeof(Effects.OpenGLAttributesEffect) };
                }
            }

			/// <summary>
			/// This converts the evaluator collection into something more usable (design time wise)
			/// by allowing all the types of evaluator to be added.
			/// </summary>
			internal class EvaluatorCollectionEditor : System.ComponentModel.Design.CollectionEditor
			{  
				public EvaluatorCollectionEditor(Type type)
                    : base(type)
                {
                }

                /// <summary>
                ///	Return the types that you want to allow the user to add into your collection. 
                ///	</summary>
				protected override Type[] CreateNewItemTypes() 
				{
					return new Type[] {typeof(Evaluators.Evaluator1D), typeof(Evaluators.Evaluator2D), typeof(Evaluators.NurbsCurve), typeof(Evaluators.NurbsSurface)}; 
				}
			}
		}		
 	}
}